package com.gin.kotlin.no_gay_alliance.worker

import android.content.Context
import android.graphics.drawable.Drawable
import android.util.Log
import androidx.work.BackoffPolicy
import androidx.work.Constraints
import androidx.work.Data
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkContinuation
import androidx.work.WorkManager
import androidx.work.WorkRequest
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.gin.kotlin.no_gay_alliance.app.App
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * 预加载头像的任务
 * @property context Context
 * @constructor
 */
class ImagePreloadWorker(val context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        val url = inputData.getString(KEY_URL) ?: return Result.failure()
        Glide.with(context).load(url).addListener(object : RequestListener<Drawable?> {
            override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable?>, isFirstResource: Boolean): Boolean {
                return false
            }

            override fun onResourceReady(resource: Drawable, model: Any, target: Target<Drawable?>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {
                //请求成功 添加路径到缓存文件
                getCacheFile(context).appendText("$url\\n")
                return false
            }
        }).preload()
        return Result.success()
    }

    companion object {
        private const val KEY_URL = "preload_url"
        private const val CACHE_FILE = "IMAGE_PRELOAD.txt"
        private val TAG = ImagePreloadWorker::class.java.simpleName

        /**
         * 获取缓存文件
         * @param context Context
         * @return File
         */
        fun getCacheFile(context: Context) = File(context.cacheDir, CACHE_FILE).also { !it.exists() && it.createNewFile() }

        /**
         * 删除缓存文件
         * @param context Context
         * @return Boolean
         */
        fun delCacheFile(context: Context) = getCacheFile(context).delete()


        @JvmStatic
        fun buildRequest(url: String) = OneTimeWorkRequest.Builder(ImagePreloadWorker::class.java)
            // 执行参数
            .setInputData(Data.Builder().putString(KEY_URL, url).build())
            // 任务限制：必须联网
            .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.UNMETERED).build())
            .setInitialDelay(200, TimeUnit.MILLISECONDS)
            // 重试策略
            .setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
            .build()


        /**
         * 开始一个系列任务
         * @param urls List<Long>
         */
        @JvmStatic
        fun start(urls: List<String>) {
            if (urls.isEmpty()) return
            Log.i(TAG, "提交图片预载: ${urls.size} 个")
            val manager = WorkManager.getInstance(App.INSTANCE)
            manager.cancelAllWorkByTag(ImagePreloadWorker::class.java.name)
            var workContinuation: WorkContinuation? = null
            val requests = urls.map { buildRequest(it) }

            requests.forEach {
                workContinuation = if (workContinuation == null)
                    manager.beginWith(it)
                else
                    workContinuation!!.then(it)
            }
            workContinuation!!.enqueue()
        }
    }
}